package com.microframework.boot.visual.service.impl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.microframework.boot.visual.model.domain.Project;
import com.microframework.boot.visual.model.domain.ProjectPage;
import com.microframework.boot.visual.model.domain.ProjectPageComponent;
import com.microframework.boot.visual.model.domain.ProjectPageComponentGroup;
import com.microframework.boot.visual.model.domain.ProjectPageGroupComponent;
import com.microframework.boot.visual.model.domain.ProjectPageHistory;
import com.microframework.boot.visual.service.IProjectPageService;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class ProjectPageServiceImpl implements IProjectPageService {

	@Override
	public void updateAllPages(String projectId, JSONObject req) {
		try {
			JSONArray pages = req.getJSONArray("pages");
			if (pages == null)
				return;

			// ==== 优化删除逻辑（核心优化点2：批量删除减少数据库交互）====
			// 1. 获取项目下所有页面ID
			List<ProjectPage> oldPages = ProjectPage.dao
					.find("select id from " + ProjectPage.TABLE_NAME + " where project_id=?", projectId);

			if (!oldPages.isEmpty()) {
				List<String> pageIds = oldPages.stream().map(p -> p.getId()).collect(Collectors.toList());

				// 2. 批量删除关联数据（使用IN语句一次性删除）
				// 2.1 删除分组-组件关联（通过组件ID）
				List<ProjectPageComponent> allComponents = ProjectPageComponent.dao
						.find("select id from " + ProjectPageComponent.TABLE_NAME + " where page_id in ("
								+ String.join(",", Collections.nCopies(pageIds.size(), "?")) + ")", pageIds.toArray());
				if (!allComponents.isEmpty()) {
					List<String> compIds = allComponents.stream().map(c -> c.getId()).collect(Collectors.toList());
					Db.use(ProjectPageGroupComponent.DS_NAME).delete("delete from " + ProjectPageGroupComponent.TABLE_NAME
							+ " where component_id in (" + String.join(",", Collections.nCopies(compIds.size(), "?")) + ")",
							compIds.toArray());
				}

				// 2.2 批量删除组件/分组/历史记录（通过页面ID）
				String inClause = String.join(",", Collections.nCopies(pageIds.size(), "?"));
				Db.use(ProjectPageComponent.DS_NAME).delete(
						"delete from " + ProjectPageComponent.TABLE_NAME + " where page_id in (" + inClause + ")",
						pageIds.toArray());
				Db.use(ProjectPageComponentGroup.DS_NAME).delete(
						"delete from " + ProjectPageComponentGroup.TABLE_NAME + " where page_id in (" + inClause + ")",
						pageIds.toArray());
				Db.use(ProjectPageHistory.DS_NAME).delete(
						"delete from " + ProjectPageHistory.TABLE_NAME + " where page_id in (" + inClause + ")",
						pageIds.toArray());

				// 3. 删除页面
				Db.use(ProjectPage.DS_NAME).delete("delete from " + ProjectPage.TABLE_NAME + " where project_id=?",
						projectId);
			}

			// ==== 优化插入逻辑（核心优化点3：批量插入提升性能）====
			List<ProjectPage> newPages = new ArrayList<>();
			List<ProjectPageComponentGroup> newGroups = new ArrayList<>();
			List<ProjectPageComponent> newComponents = new ArrayList<>();
			List<ProjectPageGroupComponent> newGroupComponents = new ArrayList<>();
			List<ProjectPageHistory> newHistories = new ArrayList<>();

			// 预遍历pages收集数据
			for (int i = 0; i < pages.size(); i++) {
				JSONObject pageJson = pages.getJSONObject(i);
				String pageId = String.valueOf(pageJson.get("id"));

				// 收集页面
				ProjectPage page = new ProjectPage();
				page.set("id", pageId).set("name", pageJson.getString("title")).setProjectId(projectId).setSortOrder(i)
						.set("page_size", pageJson.getString("pageSize")).set("bg_color", pageJson.getString("pageBgColor"))
						.set("bg_img", pageJson.getString("pageBgImg")).set("fit_mode", pageJson.getString("fitMode"))
						.set("filter",
								pageJson.get("filter") != null ? pageJson.getJSONObject("filter").toJSONString() : null)
						.set("theme_color", pageJson.getString("themeColor")).setHistoryIndex(pageJson.getInteger("historyIndex")).setBindings(pageJson.getString("bindings"));
				newPages.add(page);

				// 收集分组
				JSONArray groups = pageJson.getJSONArray("groups");
				if (groups != null) {
					for (int j = 0; j < groups.size(); j++) {
						JSONObject groupJson = groups.getJSONObject(j);
						ProjectPageComponentGroup group = new ProjectPageComponentGroup();
						group.set("id", String.valueOf(groupJson.get("id"))).set("page_id", pageId)
								.setSortOrder(j)
								.setLocked(groupJson.containsKey("locked")? groupJson.getBoolean("locked"):false)
								.set("name", groupJson.getString("name")).set("x", groupJson.getInteger("x"))
								.set("y", groupJson.getInteger("y")).set("width", groupJson.getInteger("width"))
								.set("height", groupJson.getInteger("height"))
								.setBindings( groupJson.getString("bindings"))
								.setVisible(groupJson.containsKey("visible")? groupJson.getBoolean("visible"):false)
								.setComponentIds(groupJson.getString("componentIds"))
								;
						newGroups.add(group);
					}
				}

				// 收集组件及关联关系
				JSONArray components = pageJson.getJSONArray("components");
				if (components != null) {
					for (int k = 0; k < components.size(); k++) {
						JSONObject compJson = components.getJSONObject(k);
						ProjectPageComponent comp = new ProjectPageComponent();
						comp.set("id", String.valueOf(compJson.get("id")))
							.set("page_id", pageId)
							.setSortOrder(k)
							.setLocked(compJson.containsKey("locked")? compJson.getBoolean("locked"):false)
							.setIsGrouped(compJson.containsKey("isGrouped")? compJson.getBoolean("isGrouped"):false)
							.set("group_id", compJson.getString("groupId")).set("type", compJson.getString("type"))
							.set("title", compJson.getString("title")).set("x", compJson.getDouble("x"))
							.set("y", compJson.getDouble("y")).set("width", compJson.getInteger("width"))
							.set("height", compJson.getInteger("height"))
							.set("component_id", compJson.getString("componentId"))
							.setRotate(compJson.containsKey("rotate") ? compJson.getInteger("rotate"):0)
							.setBindings( compJson.getString("bindings"))
							.setVisible(compJson.containsKey("visible")? compJson.getBoolean("visible"):false)
							.setEnterAnimation(compJson.getString("enterAnimation"))
							.setLeaveAnimation(compJson.getString("leaveAnimation"))
							.setAnimationDuration( (compJson.containsKey("animationDuration") && !StrKit.isBlank(compJson.getString("animationDuration")) ? compJson.getFloat("animationDuration"):0.5f))
							.set("bg_color", compJson.getString("bgColor")).set("config", compJson.getString("config"));
						newComponents.add(comp);

						// 收集分组-组件关联
						String groupId = compJson.getString("groupId");
						if (StringUtils.isNotBlank(groupId)) {
							ProjectPageGroupComponent gc = new ProjectPageGroupComponent();
							gc.set("group_id", groupId).set("component_id", comp.get("id"));
							newGroupComponents.add(gc);
						}
					}
				}

				// 收集历史记录
				JSONArray historyArr = pageJson.getJSONArray("history");
				if (historyArr != null) {
					for (int h = 0; h < historyArr.size(); h++) {
						JSONObject hisJson = historyArr.getJSONObject(h);
						ProjectPageHistory his = new ProjectPageHistory();
						his.set("id", String.valueOf(hisJson.get("timestamp"))).set("page_id", pageId)
								.set("type", hisJson.getString("type"))
								.set("data", hisJson.getJSONObject("data").toJSONString())
								.set("created_at", new Timestamp(hisJson.getLongValue("timestamp")));
						newHistories.add(his);
					}
				}
			}

			// 批量插入（核心优化点4：减少数据库交互次数）
			Db.use(ProjectPage.DS_NAME).batchSave(newPages, Math.min(newPages.size(), 100));
			Db.use(ProjectPageComponentGroup.DS_NAME).batchSave(newGroups, Math.min(newGroups.size(), 100));
			Db.use(ProjectPageComponent.DS_NAME).batchSave(newComponents, Math.min(newComponents.size(), 100));
			Db.use(ProjectPageGroupComponent.DS_NAME).batchSave(newGroupComponents,
					Math.min(newGroupComponents.size(), 100));
			Db.use(ProjectPageHistory.DS_NAME).batchSave(newHistories, Math.min(newHistories.size(), 100));
		}catch (Exception e) {
            throw new RuntimeException(e.getMessage()); // 触发回滚
		}
	}

	@Override
	public JSONObject getPagesByProjectId(String projectId) {
	    JSONObject result = new JSONObject();
	    JSONArray pagesArray = new JSONArray();
	    
	    Project project=Project.dao.findById(projectId);
	    result.put("project",project);

	    // 1. 查询项目下的所有页面
	    List<ProjectPage> pages = ProjectPage.dao.find("select * from " + ProjectPage.TABLE_NAME + " where project_id=? order by sort_order asc", projectId);
	    if (pages == null || pages.isEmpty()) {
	        result.put("pages", pagesArray);
	        return result;
	    }

	    // 2. 遍历每个页面，构建完整结构
	    for (ProjectPage page : pages) {
	        JSONObject pageJson = new JSONObject();
	        pageJson.put("id", page.getId());
	        pageJson.put("title", page.getName());
	        pageJson.put("pageSize", page.getPageSize());
	        pageJson.put("pageBgColor", page.getBgColor());
	        pageJson.put("pageBgImg", page.getBgImg());
	        pageJson.put("fitMode", page.getFitMode());
	        pageJson.put("themeColor", page.getThemeColor());
	        pageJson.put("historyIndex", page.getHistoryIndex());
	        pageJson.put("bindings", 
            	    StrKit.isBlank(page.getBindings())
        	        ? new JSONArray()
        	        : JSONArray.parseArray(page.getBindings()));
	        
	        
	        // 处理filter字段（存储为JSON字符串）
	        if (page.get("filter") != null) {
	            pageJson.put("filter", JSONObject.parseObject(page.getFilter()));
	        }

	        // 2.1 查询并添加分组数据
	        JSONArray groupsArray = new JSONArray();
	        List<ProjectPageComponentGroup> groups = ProjectPageComponentGroup.dao.find(
	            "select * from " + ProjectPageComponentGroup.TABLE_NAME + " where page_id=? order by sort_order asc ", 
	            page.getId());
	        
	        for (ProjectPageComponentGroup group : groups) {
	            JSONObject groupJson = new JSONObject();
	            groupJson.put("id", group.getId());
	            groupJson.put("name", group.getName());
	            groupJson.put("x", group.getX());
	            groupJson.put("y", group.getY());
	            groupJson.put("width", group.getWidth());
	            groupJson.put("height", group.getHeight());
	            groupJson.put("locked", group.getLocked());
	            groupJson.put("bindings",
	            	    StrKit.isBlank(group.getBindings())
	            	        ? new JSONArray()
	            	        : JSONArray.parseArray(group.getBindings()));
	            groupJson.put("visible", group.getVisible());
	            groupJson.put("componentIds",
	            	    StrKit.isBlank(group.getComponentIds())
	            	        ? new JSONArray()
	            	        : JSONArray.parseArray(group.getComponentIds()));
	            groupsArray.add(groupJson);
	        }
	        pageJson.put("groups", groupsArray);

	        // 2.2 查询并添加组件数据
	        JSONArray componentsArray = new JSONArray();
	        List<ProjectPageComponent> components = ProjectPageComponent.dao.find(
	            "select * from " + ProjectPageComponent.TABLE_NAME + " where page_id=? order by sort_order asc", 
	            page.getId());
	        
	        for (ProjectPageComponent component : components) {
	            JSONObject compJson = new JSONObject();
	            compJson.put("id", component.getId());
	            compJson.put("componentId", component.getComponentId());
	            compJson.put("groupId", component.getGroupId());
	            compJson.put("type", component.getType());
	            compJson.put("title", component.getTitle());
	            compJson.put("locked", component.getLocked());
	            compJson.put("isGrouped", component.getIsGrouped());
	            compJson.put("x", component.getX());
	            compJson.put("y", component.getY());
	            compJson.put("rotate", component.getRotate());
	            compJson.put("width", component.getWidth());
	            compJson.put("height", component.getHeight());
	            compJson.put("bgColor", component.getBgColor());
	            compJson.put("config", StrKit.isBlank(component.getConfig())?new JSONObject(): JSONObject.parseObject(component.getConfig()));
	            compJson.put("bindings",
	            	    StrKit.isBlank(component.getBindings())
	            	        ? new JSONArray()
	            	        : JSONArray.parseArray(component.getBindings()));
	            compJson.put("visible", component.getVisible());
	            compJson.put("enterAnimation", component.getEnterAnimation());
	            compJson.put("leaveAnimation", component.getLeaveAnimation());
	            compJson.put("animationDuration", component.getAnimationDuration());
	            componentsArray.add(compJson);
	        }
	        pageJson.put("components", componentsArray);

	        // 2.3 查询分组-组件关联关系（如果前端需要）
	        JSONArray groupRelationsArray = new JSONArray();
	        if (!components.isEmpty()) {
	            List<String> compIds = components.stream().map(c -> c.getId()).collect(Collectors.toList());
	            List<ProjectPageGroupComponent> relations = ProjectPageGroupComponent.dao.find(
	                "select * from " + ProjectPageGroupComponent.TABLE_NAME + 
	                " where component_id in (" + String.join(",", java.util.Collections.nCopies(compIds.size(), "?")) + ")",
	                compIds.toArray());
	            
	            for (ProjectPageGroupComponent rel : relations) {
	                JSONObject relJson = new JSONObject();
	                relJson.put("groupId", rel.getGroupId());
	                relJson.put("componentId", rel.getComponentId());
	                groupRelationsArray.add(relJson);
	            }
	        }
	        pageJson.put("groupComponents", groupRelationsArray);

	        // 2.4 查询并添加历史记录
	        JSONArray historyArray = new JSONArray();
	        List<ProjectPageHistory> histories = ProjectPageHistory.dao.find(
	            "select * from " + ProjectPageHistory.TABLE_NAME + " where page_id=? order by created_at desc", 
	            page.getId());
	        
	        for (ProjectPageHistory history : histories) {
	            JSONObject hisJson = new JSONObject();
	            hisJson.put("timestamp", history.getId());
	            hisJson.put("type", history.getType());
	            hisJson.put("data", JSONObject.parseObject(history.getData()));
	            hisJson.put("createdAt", history.getCreatedAt().getTime());
	            historyArray.add(hisJson);
	        }
	        pageJson.put("history", historyArray);
	        pagesArray.add(pageJson);
	    }
	    result.put("pages", pagesArray);
	    return result;
	}

}
